package leetcode.code0794;

import leetcode.IDebug;
import leetcode.helper.HelpDebug;
import leetcode.helper.MaxDebug;

public class Solution794 implements IDebug {

	private int LIMIT = 3;
	private char X = 'X';
	private char O = 'O';
	private int Sign1 = 0b100;
	private int Sign0 = 0b010;
	private int Sign2 = 0b001;
	private int Finish = 0b111;

	public boolean validTicTacToe(String[] board) {
		int len = board.length;
		if (len != LIMIT)
			return false;
		int numofx = 0;
		int numofo = 0;
		int[] recordx = new int[LIMIT];// x的位置
		int[] recordo = new int[LIMIT];// o的位置
		for (int i = 0; i < LIMIT; i++) {// 收录字符
			char[] str = board[i].toCharArray();
			if (str.length != LIMIT)
				return false;
			for (int j = 0; j < LIMIT; j++) {
				char c = str[j];
				if (c == X) {
					numofx++;
					recordx[i] |= 1 << j;
				} else if (c == O) {
					numofo++;
					recordo[i] |= 1 << j;
				}
			}
		}
		if (numofx != numofo && numofx - numofo != 1) {// x先手检查
			return false;
		}
		boolean winx = false;
		boolean wino = false;
		for (int i = 0; i < LIMIT; i++) {
			if (recordx[i] == Finish) {
				winx = true;
			}
			if (recordo[i] == Finish) {
				wino = true;
			}
		}
		wino = wino ? wino : this.checkColumn(recordo);// o列完成
		winx = winx ? winx : this.checkColumn(recordx);// x列完成
		wino = wino ? wino : this.checkDiagonal(recordo);// o对角线完成
		winx = winx ? winx :this.checkDiagonal(recordx);// x对角线完成
		if ((wino && winx) || (wino && numofx > numofo)) {
			return false;
		}
		if (winx && numofx <= numofo) {
			return false;
		}
		return true;
	}

	private boolean checkColumn(int[] record) {
		return this.column(record, Sign1) || this.column(record, Sign0) || this.column(record, Sign2);
	}

	private boolean column(int[] record, int sign) {
		return this.check(record, 0, sign) && this.check(record, 1, sign) && this.check(record, 2, sign);
	}

	private boolean checkDiagonal(int[] record) {
		if (this.check(record, 0, Sign1) && this.check(record, 1, Sign0) && this.check(record, 2, Sign2)) {
			return true;
		}
		if (this.check(record, 2, Sign1) && this.check(record, 1, Sign0) && this.check(record, 0, Sign2)) {
			return true;
		}
		return false;
	}

	private boolean check(int[] record, int index, int sign) {
		return (record[index] & sign) == sign;
	}

	@Override
	public void debug1() {
		HelpDebug.compare(false, this.validTicTacToe(HelpDebug.str2array2("[\"O  \",\"   \",\"   \"]")));

	}

	@Override
	public void debug2() {
		// TODO Auto-generated method stub
		HelpDebug.compare(false, this.validTicTacToe(HelpDebug.str2array2("[\"XOX\",\" X \",\"   \"]")));
	}

	@Override
	public void debug3() {
		// TODO Auto-generated method stub
		HelpDebug.compare(false, this.validTicTacToe(HelpDebug.str2array2("[\"XXX\",\"   \",\"OOO\"]")));
	}

	@Override
	public void debug4() {
		// TODO Auto-generated method stub
		HelpDebug.compare(true, this.validTicTacToe(HelpDebug.str2array2("[\"XOX\",\"O O\",\"XOX\"]")));
	}

	public void debug5() {
		// TODO Auto-generated method stub
		HelpDebug.compare(true, this.validTicTacToe(HelpDebug.str2array2("[\"XXX\",\"OOX\",\"OOX\"]")));
	}

	public void debug6() {
		// TODO Auto-generated method stub
		HelpDebug.compare(true, this.validTicTacToe(HelpDebug.str2array2("[\"XOX\",\"OXO\",\"XOX\"]")));
	}

	public void debug7() {
		// TODO Auto-generated method stub
		HelpDebug.compare(false, this.validTicTacToe(HelpDebug.str2array2("[\"XXX\",\"XOO\",\"OO \"]")));
	}

	public void debug8() {
		// TODO Auto-generated method stub
		HelpDebug.compare(false, this.validTicTacToe(HelpDebug.str2array2("[\"OXX\",\"XOX\",\"OXO\"]")));
	}
	public void debug9() {
		// TODO Auto-generated method stub
		HelpDebug.compare(true, this.validTicTacToe(HelpDebug.str2array2("[\"XOX\",\"OOX\",\"XO \"]")));
	}

	public static void main(String[] args) {
		Solution794 so = new Solution794();
		so.debug9();
		so.debug8();
		so.debug7();
		so.debug6();
		so.debug5();
		so.debug4();
		so.debug1();
		MaxDebug.debug14(so);
	}

}
